package org.github.manx98.jlibhac.tools.fssystem;

import lombok.extern.slf4j.Slf4j;
import org.github.manx98.jlibhac.common.StackTraceUtil;
import org.github.manx98.jlibhac.fs.IStorage;
import org.github.manx98.jlibhac.util.BitUtil;

import java.io.IOException;

/**
 * @author Manx98
 * @version 1.0
 * @since 2022/10/3 20:23
 */
@Slf4j
public class SectorStorage extends IStorage {
    protected final IStorage baseStorage;
    protected final int sectorSize;
    protected final int sectorCount;
    private final long length;
    private final boolean leaveOpen;

    public SectorStorage(IStorage baseStorage, int sectorSize, boolean leaveOpen) {
        super(0);
        this.baseStorage = baseStorage;
        this.sectorSize = sectorSize;
        long baseSize = baseStorage.getSize();

        this.sectorCount = (int) BitUtil.divideUp(baseSize, sectorSize);
        this.length = baseSize;

        this.leaveOpen = leaveOpen;
    }

    @Override
    public void read(long offset, byte[] destination, int destOffset, int len) throws IOException {
        validateSize(destination.length, offset);
        baseStorage.read(offset, destination, destOffset, len);
    }

    private void validateSize(int size, long offset) {
        if (size < 0)
            throw new IllegalArgumentException("Size must be non-negative");
        if (offset < 0)
            throw new IllegalArgumentException("Offset must be non-negative");
        if (offset % sectorSize != 0)
            throw new IllegalArgumentException("Offset must be a multiple of " + sectorSize);
    }

    @Override
    public void close() throws IOException {
        if (!leaveOpen) {
            baseStorage.close();
        }
    }

    @Override
    public long getSize() {
        return length;
    }

    public int getSectorCount() {
        return sectorCount;
    }

    public int getSectorSize() {
        return sectorSize;
    }
}
